<script lang="ts" setup>
import { onMounted, reactive, ref } from 'vue'
import { jsonp } from 'vue-jsonp'

interface MapProps {
  location?: {
    latitude: number
    longitude: number
  }
}

const props = withDefaults(defineProps<MapProps>(), {
  // 默认北京
  location: () => ({
    latitude: 39.910506,
    longitude: 116.39926431433355
  })
})

let map: any = null
const state = reactive<any>({
  markerLayer: '',
  marker: null,
  infoWindow: null,
  value: 1,
  lat: 0,
  lng: 0
})
const TMap = (window as any).TMap
const address = ref('')

onMounted(() => {
  init()
})

/**
 * 初始化地图
 */
const init = () => {
  // 位置
  const { location } = props
  const center = new TMap.LatLng(location.latitude, location.longitude)
  map = new TMap.Map(document.getElementById('container'), {
    center: center, // 设置地图中心点坐标
    zoom: 11, // 设置地图缩放级别
    viewMode: '2D'
  })
  addImgMarker(center)
  // 监听地图点击事件
  map.on('click', (e: any) => {
    // 清除点标记
    state.marker.setMap(null)
    // 关闭信息窗关闭
    state.infoWindow.close()
    state.marker = null
    // 添加点标记
    addImgMarker(e.latLng)
    // 地址解析
    getAddress(e)
  })

  // 初始化infoWindow
  state.infoWindow = new TMap.InfoWindow({
    map: map,
    position: center,
    offset: { x: 0, y: -32 } // 设置信息窗相对position偏移像素
  })
  // 初始关闭信息窗关闭
  state.infoWindow.close()
}

/**
 * 添加点标记
 * @param data data
 */
const addImgMarker = (data: any) => {
  state.marker = new TMap.MultiMarker({
    map: map,
    geometries: [{ position: new TMap.LatLng(data.lat, data.lng) }]
  })
}

/**
 * 逆地址解析
 * @param e 待解析经纬度
 */
const getAddress = (e: any) => {
  const geocoder = new TMap.service.Geocoder() // 新建一个正逆地址解析类
  const location = new TMap.LatLng(e.latLng.lat, e.latLng.lng)
  geocoder.getAddress({ location: location }).then((res: any) => {
    if (res.status === 0) {
      state.infoWindow.open()
      state.infoWindow.setPosition(e.latLng) // 设置信息窗位置
      state.infoWindow.setContent(res.result.address) // 设置信息窗内容
    }
  })
}

/**
 * 修改地图类型
 * @param e e
 */
const changebasemap = (val: number) => {
  if (val === 1) {
    map.setBaseMap({ type: 'vector' })
  } else if (val === 2) {
    map.setBaseMap({ type: 'satellite' })
  }
}

/*
 *
 *  querySearch: 搜索
 */
const querySearchAsync = (queryString: string, cb: (arg: any) => void) => {
  const data = {
    key: 'TLRBZ-7XM6P-YQ5DV-L47TN-HN3UJ-K5BPM',
    output: 'jsonp',
    keyword: queryString
  }
  jsonp('https://apis.map.qq.com/ws/place/v1/suggestion', {
    ...data
  })
    .then((res) => {
      const results = res.data.map((item: any) => {
        let obj = {
          value: item.address,
          address: item.address
        }
        return obj
      })
      cb(results)
    })
    .catch((err) => err)
}

/*
 *
 * getLocaltuion:  地址转坐标
 */
const getLocaltuion = () => {
  const data = {
    key: 'TLRBZ-7XM6P-YQ5DV-L47TN-HN3UJ-K5BPM',
    smart_address: address.value
  }
  jsonp('https://apis.map.qq.com/ws/geocoder/v1/?address=', {
    ...data
  })
    .then((res) => {
      console.log(res, 'res-')
      const { result, message } = res
      if (message === 'Success') {
        // 成功
        const { location } = result
        state.lat = location.lat
        state.lng = location.lng
        map.setCenter(new TMap.LatLng(location.lat, location.lng))
        reloadMap()
      }
    })
    .catch((err) => {
      console.log(err)
    })
}

/*
 *
 *reloadMap: 重载地图
 */
const reloadMap = () => {
  ;(document.getElementById('container') as any).innerHTML = ''
  let center = new TMap.LatLng(state.lat, state.lng)
  map = new TMap.Map(document.getElementById('container'), {
    center: center, // 设置地图中心点坐标
    zoom: 11, // 设置地图缩放级别
    viewMode: '2D'
  })
  // markerLayer()
}
</script>
<template>
  <div class="search-map">
    <el-autocomplete
      class="search"
      v-model="address"
      :fetch-suggestions="querySearchAsync"
      placeholder="请输入详细地址"
      :trigger-on-focus="false"
    />
    <el-button class="search-btn" type="primary" @click="getLocaltuion">
      搜索
    </el-button>
  </div>
  <div id="container" class="container"></div>
  <div class="map">
    <CERadioGroup
      v-model="state.value"
      :options="[
        { value: 1, label: '地图' },
        { value: 2, label: '卫星' }
      ]"
      @change="changebasemap"
    />
  </div>
</template>
<style lang="scss" scoped>
.container {
  width: 100%;
  height: 100%;
  border: 10px solid #ececec;
  position: relative;
}
.map {
  position: absolute;
  z-index: 9999;
  background-color: black;
  opacity: 0.6;
  padding-left: 10px;
  padding-right: 10px;
}
.search-map {
  width: 100%;
  display: flex;
  align-items: center;
  margin-bottom: 20px;
  .search-btn {
    margin-left: 20px;
  }
  :deep(.search) {
    width: 400px !important;
  }
}
</style>
